﻿// --------------------------------------------------------------------------------------------------------------------
// <copyright file="Serialization.cs" company="Mar3ek">
//   This code is licensed under the Mozilla Public License 2.0.
//   You can find the full license text at the following address:
//   https://winkee.codeplex.com/license
// </copyright>
// <summary>
//   Defines the Serialization type.
// </summary>
// --------------------------------------------------------------------------------------------------------------------

namespace WinKee.Common
{
    using System;
    using System.IO;
    using System.IO.Compression;
    using System.Net;

    /// <summary>
    /// A class providing helper methods for serialization.
    /// </summary>
    internal static class Serialization
    {
        /// <summary>
        /// Serializes the specified object.
        /// </summary>
        /// <param name="obj">
        /// The object to serialize.
        /// </param>
        /// <returns>
        /// A string representation of the given object.
        /// </returns>
        public static string Serialize(this object obj)
        {
            using (var ms = new MemoryStream())
            {
                using (var stream = new DeflateStream(ms, CompressionMode.Compress, true))
                {
                    var ser = new System.Runtime.Serialization.Json.DataContractJsonSerializer(obj.GetType(), SuspensionManager.KnownTypes);
                    ser.WriteObject(stream, obj);
                }

                var data = new byte[ms.Length];
                ms.Seek(0, SeekOrigin.Begin);
                ms.Read(data, 0, data.Length);
                return WebUtility.UrlEncode(Convert.ToBase64String(data));
            }
            
        }

        /// <summary>
        /// Deserializes the given string into an object.
        /// </summary>
        /// <param name="input">
        /// The input string.
        /// </param>
        /// <typeparam name="T">
        /// The target type to deserialize.
        /// </typeparam>
        /// <returns>
        /// The deserialized object.
        /// </returns>
        public static T Deserialize<T>(this string input)
        {
            if (string.IsNullOrEmpty(input))
            {
                return default(T);
            }

            var ser = new System.Runtime.Serialization.Json.DataContractJsonSerializer(typeof(T));
            using (var stream = new DeflateStream(new MemoryStream(Convert.FromBase64String(WebUtility.UrlDecode(input))), CompressionMode.Decompress))
            {
                return (T)ser.ReadObject(stream);
            } 
        }
    }
}
